from datetime import datetime

import uvicorn
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from apscheduler.triggers.cron import CronTrigger
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from starlette.responses import JSONResponse

from config import settings
from src import apis
from utils.logger import create_logger

logger = create_logger(__name__)


class CustomError(Exception):
    def __init__(self, status, message):
        self.status = status
        self.message = message


app = FastAPI()
# 这行一定要放在上面，至少要在通用拦截之前
app.include_router(apis.router)

# 全局调度器（可选：也可放在依赖注入或独立模块中）
scheduler = AsyncIOScheduler()

# ============ 使用 lifespan 管理生命周期 ============
# 启动时运行
@app.on_event("startup")
async def startup_event():
    scheduler.add_job(
        apis.generate_station_data_scheduler,
        trigger=CronTrigger(minute='20,50', second=0),  # 每25分钟执行一次
        id="every_5_minutes_pressure_data",
        max_instances=1,
        misfire_grace_time=60
    )
    scheduler.start()
    logger.info("APScheduler 已启动")

# 关闭时运行
@app.on_event("shutdown")
async def shutdown_event():
    scheduler.shutdown()
    logger.info("APScheduler 已关闭")

app.get("/test")
def home():
    return {"message": "Hello from FastAPI!", "time": get_current()}


# 设置允许的源、方法和头部信息
origins = ["*"]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


@app.exception_handler(CustomError)
async def custom_error_handler(request, exc):
    return JSONResponse(
        status_code=exc.status,
        content={"status": exc.status, "message": exc.message}
    )


def get_current():
    """
    获取当前时间
    @return: yyyy-MM-dd HH:mm:ss 时间字符串
    """
    return datetime.now().strftime("%Y-%m-%d %H:%M:%S")


if __name__ == "__main__":
    start_port = settings["project"]["start_port"]

    # 尝试将 start_port 转换为正整数
    try:
        port = int(start_port)
        if port <= 0:
            raise ValueError("Port must be positive.")
    except (ValueError, TypeError):
        logger.warning(f"无效的端口配置: {start_port}，将使用默认端口 6112")
        port = 6112

    logger.info(f"启动端口：{port}")
    uvicorn.run(app, host="0.0.0.0", port=port)